use super::super::memory::{VectorBuffer, CacheAlignedArray, GLOBAL_MEMORY_POOL};
use super::super::parallel::simd;
use super::super::tasks::{BatchExecutor, GLOBAL_TASK_SCHEDULER, TaskConfig, TaskPriority, TaskType};
use rayon::prelude::*;
use std::sync::Arc;
use serde::{Deserialize, Serialize};

/// 优化的技术指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizedIndicatorResult {
    pub sma_results: Vec<Vec<f64>>,
    pub ema_results: Vec<Vec<f64>>,
    pub rsi_result: Vec<f64>,
    pub macd_result: MACDResult,
    pub bollinger_result: BollingerResult,
    pub stochastic_result: StochasticResult,
    pub computation_time_ms: u64,
}

/// MACD计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MACDResult {
    pub macd: Vec<f64>,
    pub signal: Vec<f64>,
    pub histogram: Vec<f64>,
}

/// 布林带计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BollingerResult {
    pub upper: Vec<f64>,
    pub middle: Vec<f64>,
    pub lower: Vec<f64>,
}

/// 随机指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StochasticResult {
    pub k: Vec<f64>,
    pub d: Vec<f64>,
}

/// 优化的技术指标计算器
pub struct OptimizedIndicatorCalculator {
    /// 是否使用SIMD优化
    use_simd: bool,
    /// 是否使用并行计算
    use_parallel: bool,
    /// 批处理大小
    batch_size: usize,
}

impl OptimizedIndicatorCalculator {
    /// 创建新的优化技术指标计算器
    pub fn new(use_simd: bool, use_parallel: bool, batch_size: usize) -> Self {
        Self {
            use_simd,
            use_parallel,
            batch_size,
        }
    }
    
    /// 计算所有技术指标
    pub fn calculate_all_indicators(
        &self,
        prices: &[f64],
        volumes: &[f64],
        high_prices: &[f64],
        low_prices: &[f64],
    ) -> OptimizedIndicatorResult {
        let start_time = std::time::Instant::now();
        
        // 创建结果缓冲区
        let mut sma_results = Vec::new();
        let mut ema_results = Vec::new();
        
        // 计算SMA指标（多周期）
        let sma_periods = [5, 10, 20, 50, 200];
        if self.use_parallel {
            sma_results = sma_periods.par_iter()
                .map(|&period| self.calculate_sma(prices, period))
                .collect();
        } else {
            for &period in &sma_periods {
                sma_results.push(self.calculate_sma(prices, period));
            }
        }
        
        // 计算EMA指标（多周期）
        let ema_periods = [12, 26, 50, 100];
        if self.use_parallel {
            ema_results = ema_periods.par_iter()
                .map(|&period| self.calculate_ema(prices, period))
                .collect();
        } else {
            for &period in &ema_periods {
                ema_results.push(self.calculate_ema(prices, period));
            }
        }
        
        // 计算RSI指标
        let rsi_result = self.calculate_rsi(prices, 14);
        
        // 计算MACD指标
        let macd_result = self.calculate_macd(prices, 12, 26, 9);
        
        // 计算布林带指标
        let bollinger_result = self.calculate_bollinger_bands(prices, 20, 2.0);
        
        // 计算随机指标
        let stochastic_result = self.calculate_stochastic(prices, high_prices, low_prices, 14, 3);
        
        let computation_time = start_time.elapsed().as_millis() as u64;
        
        OptimizedIndicatorResult {
            sma_results,
            ema_results,
            rsi_result,
            macd_result,
            bollinger_result,
            stochastic_result,
            computation_time_ms: computation_time,
        }
    }
    
    /// 计算简单移动平均线
    pub fn calculate_sma(&self, prices: &[f64], period: usize) -> Vec<f64> {
        if prices.len() < period {
            return Vec::new();
        }
        
        if self.use_simd {
            unsafe {
                simd::vector_sma(prices, period)
            }
        } else {
            let mut result = Vec::with_capacity(prices.len() - period + 1);
            let mut sum = prices[0..period].iter().sum::<f64>();
            result.push(sum / period as f64);
            
            for i in 0..prices.len() - period {
                sum = sum - prices[i] + prices[i + period];
                result.push(sum / period as f64);
            }
            
            result
        }
    }
    
    /// 计算指数移动平均线
    pub fn calculate_ema(&self, prices: &[f64], period: usize) -> Vec<f64> {
        if prices.is_empty() {
            return Vec::new();
        }
        
        let alpha = 2.0 / (period as f64 + 1.0);
        
        if self.use_simd {
            unsafe {
                simd::vector_ema(prices, alpha)
            }
        } else {
            let mut result = Vec::with_capacity(prices.len());
            result.push(prices[0]);
            
            for i in 1..prices.len() {
                let ema = alpha * prices[i] + (1.0 - alpha) * result[i-1];
                result.push(ema);
            }
            
            result
        }
    }
    
    /// 计算相对强弱指标
    pub fn calculate_rsi(&self, prices: &[f64], period: usize) -> Vec<f64> {
        if prices.len() <= period {
            return Vec::new();
        }
        
        if self.use_simd {
            unsafe {
                simd::vector_rsi(prices, period)
            }
        } else {
            // 创建价格变化、上涨和下跌的缓冲区
            let mut gains = VectorBuffer::<f64>::with_capacity(prices.len() - 1);
            let mut losses = VectorBuffer::<f64>::with_capacity(prices.len() - 1);
            
            // 计算价格变化
            for i in 1..prices.len() {
                let change = prices[i] - prices[i-1];
                gains.as_mut().push(change.max(0.0));
                losses.as_mut().push((-change).max(0.0));
            }
            
            // 计算初始平均值
            let mut avg_gain = gains.as_ref()[0..period].iter().sum::<f64>() / period as f64;
            let mut avg_loss = losses.as_ref()[0..period].iter().sum::<f64>() / period as f64;
            
            let mut result = Vec::with_capacity(prices.len() - period);
            result.push(100.0 - (100.0 / (1.0 + avg_gain / avg_loss.max(f64::EPSILON))));
            
            // 计算RSI
            for i in period..gains.as_ref().len() {
                avg_gain = ((period as f64 - 1.0) * avg_gain + gains.as_ref()[i]) / period as f64;
                avg_loss = ((period as f64 - 1.0) * avg_loss + losses.as_ref()[i]) / period as f64;
                
                let rs = avg_gain / avg_loss.max(f64::EPSILON);
                result.push(100.0 - (100.0 / (1.0 + rs)));
            }
            
            result
        }
    }
    
    /// 计算MACD指标
    pub fn calculate_macd(&self, prices: &[f64], fast_period: usize, slow_period: usize, signal_period: usize) -> MACDResult {
        // 计算快速和慢速EMA
        let fast_ema = self.calculate_ema(prices, fast_period);
        let slow_ema = self.calculate_ema(prices, slow_period);
        
        // 确保两个EMA的长度匹配
        let min_len = fast_ema.len().min(slow_ema.len());
        let mut macd = Vec::with_capacity(min_len);
        
        // 计算MACD线
        for i in 0..min_len {
            macd.push(fast_ema[i] - slow_ema[i]);
        }
        
        // 计算信号线（MACD的EMA）
        let signal = self.calculate_ema(&macd, signal_period);
        
        // 计算柱状图
        let mut histogram = Vec::with_capacity(signal.len());
        for i in 0..signal.len() {
            histogram.push(macd[i] - signal[i]);
        }
        
        MACDResult {
            macd,
            signal,
            histogram,
        }
    }
    
    /// 计算布林带指标
    pub fn calculate_bollinger_bands(&self, prices: &[f64], period: usize, num_std: f64) -> BollingerResult {
        // 计算移动平均
        let sma = self.calculate_sma(prices, period);
        
        let mut upper = Vec::with_capacity(sma.len());
        let mut lower = Vec::with_capacity(sma.len());
        
        // 计算上下轨
        for i in 0..sma.len() {
            let start_idx = i;
            let end_idx = i + period;
            let slice = &prices[start_idx..end_idx];
            
            let std_dev = if self.use_simd {
                unsafe { simd::vector_std(slice) }
            } else {
                let mean = slice.iter().sum::<f64>() / slice.len() as f64;
                let variance = slice.iter().map(|&x| (x - mean).powi(2)).sum::<f64>() / slice.len() as f64;
                variance.sqrt()
            };
            
            upper.push(sma[i] + num_std * std_dev);
            lower.push(sma[i] - num_std * std_dev);
        }
        
        BollingerResult {
            upper,
            middle: sma,
            lower,
        }
    }
    
    /// 计算随机指标
    pub fn calculate_stochastic(&self, prices: &[f64], high_prices: &[f64], low_prices: &[f64], k_period: usize, d_period: usize) -> StochasticResult {
        if prices.len() < k_period {
            return StochasticResult { k: Vec::new(), d: Vec::new() };
        }
        
        let mut k = Vec::with_capacity(prices.len() - k_period + 1);
        
        // 计算%K
        for i in k_period-1..prices.len() {
            let current_close = prices[i];
            let mut highest_high = f64::NEG_INFINITY;
            let mut lowest_low = f64::INFINITY;
            
            for j in i-(k_period-1)..=i {
                highest_high = highest_high.max(high_prices[j]);
                lowest_low = lowest_low.min(low_prices[j]);
            }
            
            let range = highest_high - lowest_low;
            let k_value = if range == 0.0 { 50.0 } else { (current_close - lowest_low) / range * 100.0 };
            k.push(k_value);
        }
        
        // 计算%D（%K的移动平均）
        let d = self.calculate_sma(&k, d_period);
        
        StochasticResult { k, d }
    }
    
    /// 批量计算多个股票的技术指标
    pub fn batch_calculate_indicators(
        &self,
        stock_data: Vec<StockData>,
    ) -> Vec<OptimizedIndicatorResult> {
        if self.use_parallel {
            // 使用批处理执行器进行并行计算
            let executor = BatchExecutor::new(stock_data, self.batch_size, |batch| {
                batch.iter().map(|data| {
                    self.calculate_all_indicators(
                        &data.prices,
                        &data.volumes,
                        &data.high_prices,
                        &data.low_prices,
                    )
                }).collect()
            });
            
            executor.execute_parallel()
        } else {
            // 串行计算
            stock_data.iter().map(|data| {
                self.calculate_all_indicators(
                    &data.prices,
                    &data.volumes,
                    &data.high_prices,
                    &data.low_prices,
                )
            }).collect()
        }
    }
    
    /// 异步计算技术指标
    pub async fn calculate_indicators_async(
        &self,
        prices: Vec<f64>,
        volumes: Vec<f64>,
        high_prices: Vec<f64>,
        low_prices: Vec<f64>,
    ) -> OptimizedIndicatorResult {
        // 创建任务配置
        let config = TaskConfig {
            priority: TaskPriority::Normal,
            task_type: TaskType::Computation,
            timeout_ms: Some(5000),
            max_retries: 1,
            cancellable: true,
        };
        
        // 创建任务
        let task_id = format!("indicator_calc_{}", uuid::Uuid::new_v4());
        let task_name = "Technical Indicator Calculation".to_string();
        
        let use_simd = self.use_simd;
        let use_parallel = self.use_parallel;
        let batch_size = self.batch_size;
        
        let calculator = Arc::new(OptimizedIndicatorCalculator::new(use_simd, use_parallel, batch_size));
        let prices_clone = prices.clone();
        let volumes_clone = volumes.clone();
        let high_prices_clone = high_prices.clone();
        let low_prices_clone = low_prices.clone();
        
        // 提交任务到调度器
        let result_receiver = GLOBAL_TASK_SCHEDULER.submit(
            super::super::tasks::Task::new(
                task_id,
                task_name,
                config,
                move || {
                    let result = calculator.calculate_all_indicators(
                        &prices_clone,
                        &volumes_clone,
                        &high_prices_clone,
                        &low_prices_clone,
                    );
                    Ok(result)
                },
            )
        ).await;
        
        // 等待任务完成
        match result_receiver.await {
            Ok(task_result) => {
                match task_result.result {
                    Ok(result) => result,
                    Err(_) => {
                        // 如果任务失败，使用同步方法计算
                        self.calculate_all_indicators(&prices, &volumes, &high_prices, &low_prices)
                    }
                }
            },
            Err(_) => {
                // 如果接收结果失败，使用同步方法计算
                self.calculate_all_indicators(&prices, &volumes, &high_prices, &low_prices)
            }
        }
    }
}

/// 单只股票的数据
#[derive(Clone)]
pub struct StockData {
    pub symbol: String,
    pub prices: Vec<f64>,
    pub volumes: Vec<f64>,
    pub high_prices: Vec<f64>,
    pub low_prices: Vec<f64>,
}

/// 创建缓存友好的股票数据结构
pub fn create_cache_aligned_stock_data(data: &[StockData]) -> CacheAlignedArray<f64> {
    let stock_count = data.len();
    if stock_count == 0 {
        return CacheAlignedArray::new(0, 0);
    }
    
    let price_count = data[0].prices.len();
    
    // 创建缓存对齐的数组
    let mut aligned_data = CacheAlignedArray::new(stock_count, price_count);
    
    // 填充数据
    for (i, stock) in data.iter().enumerate() {
        for (j, &price) in stock.prices.iter().enumerate() {
            aligned_data.set(i, j, price).unwrap();
        }
    }
    
    aligned_data
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_optimized_sma() {
        let prices = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
        let calculator = OptimizedIndicatorCalculator::new(true, false, 100);
        
        let sma = calculator.calculate_sma(&prices, 3);
        assert_eq!(sma.len(), prices.len() - 3 + 1);
        assert!((sma[0] - 2.0).abs() < 1e-6);
        assert!((sma[sma.len() - 1] - 9.0).abs() < 1e-6);
    }
    
    #[test]
    fn test_optimized_ema() {
        let prices = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
        let calculator = OptimizedIndicatorCalculator::new(true, false, 100);
        
        let ema = calculator.calculate_ema(&prices, 3);
        assert_eq!(ema.len(), prices.len());
        assert!((ema[0] - 1.0).abs() < 1e-6);
    }
    
    #[test]
    fn test_optimized_rsi() {
        let prices = vec![1.0, 2.0, 3.0, 2.5, 3.5, 4.0, 3.0, 3.5, 4.5, 5.0];
        let calculator = OptimizedIndicatorCalculator::new(true, false, 100);
        
        let rsi = calculator.calculate_rsi(&prices, 3);
        assert!(!rsi.is_empty());
        assert!(rsi[0] >= 0.0 && rsi[0] <= 100.0);
    }
    
    #[test]
    fn test_optimized_bollinger_bands() {
        let prices = vec![1.0, 2.0, 3.0, 2.5, 3.5, 4.0, 3.0, 3.5, 4.5, 5.0];
        let calculator = OptimizedIndicatorCalculator::new(true, false, 100);
        
        let bb = calculator.calculate_bollinger_bands(&prices, 3, 2.0);
        assert!(!bb.middle.is_empty());
        assert_eq!(bb.upper.len(), bb.middle.len());
        assert_eq!(bb.lower.len(), bb.middle.len());
        
        // 验证上轨 > 中轨 > 下轨
        for i in 0..bb.middle.len() {
            assert!(bb.upper[i] >= bb.middle[i]);
            assert!(bb.middle[i] >= bb.lower[i]);
        }
    }
}